<template>
  <div class="app-container">
    <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
      <el-form-item label="请假类型" prop="type">
        <el-select v-model="queryParams.type" filterable placeholder="请选择请假类型" clearable>
          <el-option v-for="dict in dict?.type?.leave_type" :key="dict.value" :label="dict.label" :value="dict.value" />
        </el-select>
      </el-form-item>
      <el-form-item label="请假天数" prop="day">
        <el-input v-model="queryParams.day" placeholder="请输入请假天数" clearable @keyup.enter.native="handleQuery" />
      </el-form-item>
      <el-form-item label="流程状态" prop="flowStatus">
        <el-select v-model="queryParams.flowStatus" placeholder="请选择流程状态" clearable>
          <el-option v-for="dict in dict?.type?.flow_status" :key="dict.value" :label="dict.label"
            :value="dict.value" />
        </el-select>
      </el-form-item>
      <el-form-item label="创建者" prop="createBy">
        <el-input v-model="queryParams.createBy" placeholder="请输入创建者" clearable @keyup.enter.native="handleQuery" />
      </el-form-item>
      <el-form-item label="创建时间">
        <el-date-picker v-model="daterangeCreateTime" style="width: 240px" value-format="yyyy-MM-dd" type="daterange"
          range-separator="-" start-placeholder="开始日期" end-placeholder="结束日期"></el-date-picker>
      </el-form-item>
      <el-form-item>
        <el-button type="primary" icon="Search" size="mini" @click="handleQuery">搜索</el-button>
        <el-button icon="Refresh" size="mini" @click="resetQuery">重置</el-button>
      </el-form-item>
    </el-form>

    <el-row :gutter="10" class="mb8">
      <el-col :span="1.5">
        <el-button type="primary" plain icon="Plus" size="mini" @click="handleAdd"
          v-hasPermi="['system:leave:add']">新增</el-button>
      </el-col>
      <el-col :span="1.5">
        <el-button type="success" plain icon="Edit" size="mini" :disabled="single" @click="handleUpdate"
          v-hasPermi="['system:leave:edit']">修改</el-button>
      </el-col>
      <el-col :span="1.5">
        <el-button type="danger" plain icon="Delete" size="mini" :disabled="multiple" @click="handleDelete"
          v-hasPermi="['system:leave:remove']">删除</el-button>
      </el-col>
      <el-col :span="1.5">
        <el-button type="warning" plain icon="Download" size="mini" @click="handleExport"
          v-hasPermi="['system:leave:export']">导出</el-button>
      </el-col>
      <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
    </el-row>

    <el-table v-loading="loading" :data="leaveList" @selection-change="handleSelectionChange">
      <el-table-column type="selection" width="55" align="center" />
      <el-table-column label="主键" align="center" prop="id" />
      <el-table-column label="请假类型" align="center" prop="type">
        <template #default="scope">
          <dict-tag :options="dict.type.leave_type" :value="scope.row.type" />
        </template>
      </el-table-column>
      <el-table-column label="开始时间" align="center" prop="startTime" width="180">
        <template #default="scope">
          <span>{{ parseTime(scope.row.startTime, '{y}-{m}-{d}') }}</span>
        </template>
      </el-table-column>
      <el-table-column label="结束时间" align="center" prop="endTime" width="180">
        <template #default="scope">
          <span>{{ parseTime(scope.row.endTime, '{y}-{m}-{d}') }}</span>
        </template>
      </el-table-column>
      <el-table-column label="请假天数" align="center" prop="day" />
      <el-table-column label="流程节点名称" align="center" prop="nodeName" />
      <el-table-column label="流程状态" align="center" prop="flowStatus">
        <template #default="scope">
          <dict-tag :options="dict.type.flow_status" :value="scope.row.flowStatus" />
        </template>
      </el-table-column>
      <el-table-column label="创建者" align="center" prop="createBy" />
      <el-table-column label="创建时间" align="center" prop="createTime" width="180">
        <template #default="scope">
          <span>{{ parseTime(scope.row.createTime) }}</span>
        </template>
      </el-table-column>
      <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
        <template #default="scope">
          <el-button size="mini" type="text" icon="el-icon-edit" v-if="scope.row.nodeCode === '2'"
            @click="handleUpdate(scope.row)" v-hasPermi="['system:leave:edit']">修改</el-button>
          <el-button size="mini" type="text" v-if="scope.row.nodeCode === '2'" @click="showSubmitForm(scope.row)"
            v-hasPermi="['system:leave:edit']">提交审批</el-button>
          <el-button size="mini" type="text" v-if="scope.row.nodeType !== 2" @click="handleRevoke(scope.row.id)"
            v-hasPermi="['system:leave:edit']">撤销</el-button>
          <el-button size="mini" type="text" v-if="scope.row.nodeType !== 2"
            @click="handleTaskBackByInsId(scope.row.id)" v-hasPermi="['system:leave:edit']">拿回</el-button>
          <el-button size="mini" type="text" v-if="scope.row.nodeType !== 2" @click="handleTermination(scope.row)"
            v-hasPermi="['system:leave:edit']">终止</el-button>
          <el-button size="mini" type="text" @click="toFlowImage(scope.row.instanceId)">流程图</el-button>
          <el-button size="mini" type="text" v-if="scope.row.nodeCode === '2'" icon="el-icon-delete"
            @click="handleDelete(scope.row)" v-hasPermi="['system:leave:remove']">删除</el-button>
        </template>
      </el-table-column>
    </el-table>

    <pagination v-show="total>0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize"
      @pagination="getList" />

    <!-- 添加或修改OA 请假申请对话框 -->
    <el-dialog :title="title" v-model="open" width="800px" append-to-body>
      <el-form ref="formRef" :model="form" :rules="rules" label-width="80px">
        <el-form-item label="请假类型" prop="type">
          <el-select v-model="form.type" filterable placeholder="请选择请假类型" :disabled="disabled">
            <el-option v-for="dict in dict.type.leave_type" :key="dict.value" :label="dict.label"
              :value="dict.value"></el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="请假原因" prop="reason">
          <el-input v-model="form.reason" type="textarea" placeholder="请输入内容" :disabled="disabled" />
        </el-form-item>
        <el-form-item label="开始时间" prop="startTime">
          <el-date-picker clearable v-model="form.startTime" type="date" value-format="yyyy-MM-dd" placeholder="请选择开始时间"
            @change="calculateLeaveDays" :disabled="disabled"></el-date-picker>
        </el-form-item>
        <el-form-item label="结束时间" prop="endTime">
          <el-date-picker clearable v-model="form.endTime" type="date" value-format="yyyy-MM-dd" placeholder="请选择结束时间"
            @change="calculateLeaveDays" :disabled="disabled"></el-date-picker>
        </el-form-item>
        <el-form-item label="请假天数" prop="day">
          <el-input v-model="form.day" placeholder="请输入请假天数" :disabled="disabled" />
        </el-form-item>

        <el-form-item label="自定义流程状态" prop="flowStatus">
          <el-input v-model="flowStatus" />
          <el-tooltip class="item" effect="dark" content="warm-flow工作流默认内置了一套流程状态，如果此字段填写可以自定义流程状态">
            <i class="el-icon-question"></i>
          </el-tooltip>
        </el-form-item>

        <el-form-item label="抄送人" prop="additionalHandler">
          <el-select v-model="form.additionalHandler" multiple collapse-tags :disabled="disabled" :clearable="!disabled"
            filterable placeholder="请选择抄送人员">
            <el-option-group v-for="groupOption in groupOptions" :key="groupOption.label" :label="groupOption.label"
              :disabled="disabled">
              <el-option v-for="item in groupOption.options" :key="item.value" :label="item.label" :value="item.value">
              </el-option>
            </el-option-group>
          </el-select>
        </el-form-item>

      </el-form>
      <template #footer class="dialog-footer">
        <el-button @click="open = false">取消</el-button>
        <el-button type="primary" v-if="!disabled" @click="submitForm">确定</el-button>
        <el-button type="primary" v-if="disabled" @click="handleSubmit">提交审批</el-button>
      </template>
    </el-dialog>

    <el-dialog title="流程图" width="70%" v-model="flowChart" append-to-body>
      <WarmChart :insId="insId"></WarmChart>
    </el-dialog>

  </div>
</template>

<script setup>
  import {
    ref,
    reactive,
    onMounted,
    getCurrentInstance
  } from 'vue'
  import {
    listLeave,
    getLeave,
    delLeave,
    addLeave,
    updateLeave,
    submit,
    termination,
    revoke,
    taskBackByInsId
  } from "@/api/system/leave";
  import {
    listUser
  } from "@/api/system/user";
  import WarmChart from "@/views/flow/definition/warm_chart.vue";
  import {
    useDict
  } from '@/utils/dict'
  import {
    parseTime
  } from '@/utils/ruoyi'
  import {
    ElMessageBox,
    ElMessage
  } from 'element-plus'

  // 字典数据
  const {
    dict
  } = useDict(['leave_type', 'flow_status'])

  // 组件实例（用于访问全局方法）
  const {
    proxy
  } = getCurrentInstance()

  // 响应式变量
  const loading = ref(true)
  const ids = ref([])
  const flowChart = ref(false)
  const insId = ref(null)
  const flowStatus = ref("")
  const disabled = ref(false)
  const single = ref(true)
  const multiple = ref(true)
  const showSearch = ref(true)
  const total = ref(0)
  const leaveList = ref([])
  const title = ref("")
  const open = ref(false)
  const daterangeCreateTime = ref([])
  const groupOptions = ref([])
  const formRef = ref(null)

  // 查询参数
  const queryParams = reactive({
    pageNum: 1,
    pageSize: 10,
    type: null,
    day: null,
    flowStatus: null,
    createBy: null,
    createTime: null,
    params: {}
  })

  // 表单数据
  const form = reactive({
    id: null,
    type: null,
    reason: null,
    startTime: null,
    endTime: null,
    day: null,
    instanceId: null,
    nodeCode: null,
    nodeName: null,
    flowStatus: null,
    createBy: null,
    createTime: null,
    updateBy: null,
    updateTime: null,
    delFlag: null,
    additionalHandler: []
  })
  /** 日期范围验证 */
  const validateDateRange = (rule, value, callback) => {
    if (form.startTime && form.endTime) {
      if (new Date(form.startTime) > new Date(form.endTime)) {
        callback(new Error('开始时间不能晚于结束时间'))
      } else {
        callback()
      }
    } else {
      callback()
    }
  }

  /** 请假天数验证 */
  const validateDay = (rule, value, callback) => {
    if (form.startTime && form.endTime) {
      const timeDiff = new Date(form.endTime) - new Date(form.startTime)
      const calculatedDays = Math.ceil(timeDiff / (1000 * 60 * 60 * 24)) + 1
      if (form.day !== calculatedDays) {
        callback(new Error('请假天数应等于结束时间和开始时间之间的天数差'))
      } else {
        callback()
      }
    } else {
      callback()
    }
  }
  // 表单验证规则
  const rules = ref({
    type: [{
      required: true,
      message: "请假类型不能为空",
      trigger: "change"
    }],
    reason: [{
      required: true,
      message: "请假原因不能为空",
      trigger: "blur"
    }],
    startTime: [{
        required: true,
        message: "开始时间不能为空",
        trigger: "blur"
      },
      {
        validator: validateDateRange,
        trigger: 'change'
      }
    ],
    endTime: [{
        required: true,
        message: "结束时间不能为空",
        trigger: "blur"
      },
      {
        validator: validateDateRange,
        trigger: 'change'
      }
    ],
    day: [{
        required: true,
        message: "请假天数不能为空",
        trigger: "blur"
      },
      {
        validator: validateDay,
        trigger: 'blur'
      }
    ]
  })

  // 页面加载时执行
  onMounted(() => {
    getList()
    getUser()
  })

  /** 查询请假列表 */
  const getList = () => {
    loading.value = true
    // 处理日期范围参数
    queryParams.params = {}
    if (daterangeCreateTime.value && daterangeCreateTime.value.length === 2) {
      queryParams.params.beginCreateTime = daterangeCreateTime.value[0]
      queryParams.params.endCreateTime = daterangeCreateTime.value[1]
    }

    listLeave(queryParams)
      .then(response => {
        leaveList.value = response.rows
        total.value = response.total
      })
      .catch(error => {
        console.error('获取请假列表失败:', error)
        ElMessage.error('获取数据失败，请重试')
      })
      .finally(() => {
        loading.value = false
      })
  }

  /** 获取用户列表（用于抄送人选择） */
  const getUser = () => {
    listUser().then(response => {
      const groupOption = {
        label: '用户',
        options: response.rows.map(item => ({
          value: item.userId,
          label: item.nickName
        }))
      }
      groupOptions.value.push(groupOption)
    }).catch(error => {
      console.error('获取用户列表失败:', error)
    })
  }

  /** 搜索按钮操作 */
  const handleQuery = () => {
    queryParams.pageNum = 1
    getList()
  }

  /** 重置按钮操作 */
  const resetQuery = () => {
    daterangeCreateTime.value = []
    if (proxy?.$refs.queryForm) {
      proxy.$refs.queryForm.resetFields()
    }
    handleQuery()
  }

  /** 多选框选中处理 */
  const handleSelectionChange = (selection) => {
    ids.value = selection.map(item => item.id)
    single.value = selection.length !== 1
    multiple.value = !selection.length
  }

  /** 新增操作 */
  const handleAdd = () => {
    resetForm()
    open.value = true
    title.value = "添加OA 请假申请"
  }

  /** 修改操作 */
  const handleUpdate = (row) => {
    resetForm()
    const id = row?.id || ids.value[0]
    if (!id) return

    getLeave(id).then(response => {
      Object.assign(form, response.data)
      open.value = true
      title.value = "修改OA 请假申请"
    }).catch(error => {
      console.error('获取请假详情失败:', error)
      ElMessage.error('加载详情失败，请重试')
    })
  }

  /** 显示提交审批表单 */
  const showSubmitForm = (row) => {
    resetForm()
    const id = row?.id || ids.value[0]
    if (!id) return

    getLeave(id).then(response => {
      Object.assign(form, response.data)
      disabled.value = true
      open.value = true
      title.value = "OA请假申请审批"
    }).catch(error => {
      console.error('获取请假详情失败:', error)
      ElMessage.error('加载详情失败，请重试')
    })
  }

  /** 终止流程 */
  const handleTermination = (row) => {
    termination(row).then(() => {
      ElMessage.success("终止成功")
      getList()
    }).catch(error => {
      console.error('终止流程失败:', error)
      ElMessage.error('操作失败，请重试')
    })
  }

  /** 计算请假天数 */
  const calculateLeaveDays = () => {
    if (form.startTime && form.endTime) {
      const start = new Date(form.startTime)
      const end = new Date(form.endTime)
      const diffTime = Math.abs(end - start)
      const diffDays = Math.ceil(diffTime / (1000 * 60 * 60 * 24)) + 1 // 包含开始和结束的当天
      form.day = diffDays
    } else {
      form.day = ''
    }
  }

  /** 撤销操作 */
  const handleRevoke = (id) => {
    revoke(id).then(() => {
      ElMessage.success("撤销成功")
      open.value = false
      getList()
    }).catch(error => {
      console.error('撤销失败:', error)
      ElMessage.error('操作失败，请重试')
    })
  }

  /** 拿回操作 */
  const handleTaskBackByInsId = (id) => {
    taskBackByInsId(id).then(() => {
      ElMessage.success("拿回成功")
      open.value = false
      getList()
    }).catch(error => {
      console.error('拿回失败:', error)
      ElMessage.error('操作失败，请重试')
    })
  }

  /** 提交表单 */
  const submitForm = () => {
    if (!formRef.value) return

    formRef.value.validate((valid) => {
      if (valid) {
        if (form.id) {
          // 修改操作
          updateLeave(form).then(() => {
            ElMessage.success("修改成功")
            open.value = false
            getList()
          }).catch(error => {
            console.error('修改失败:', error)
            ElMessage.error('修改失败，请重试')
          })
        } else {
          // 新增操作
          addLeave(form, flowStatus.value).then(() => {
            ElMessage.success("新增成功")
            open.value = false
            getList()
          }).catch(error => {
            console.error('新增失败:', error)
            ElMessage.error('新增失败，请重试')
          })
        }
      }
    })
  }

  /** 提交审批 */
  const handleSubmit = () => {
    submit(form.id, flowStatus.value).then(() => {
      ElMessage.success("提交审批成功")
      open.value = false
      getList()
    }).catch(error => {
      console.error('提交审批失败:', error)
      ElMessage.error('操作失败，请重试')
    })
  }

  /** 查看流程图 */
  const toFlowImage = (instanceId) => {
    insId.value = instanceId
    flowChart.value = true
  }

  /** 删除操作 */
  const handleDelete = (row) => {
    const idsToDelete = row?.id || ids.value
    if (!idsToDelete || (Array.isArray(idsToDelete) && idsToDelete.length === 0)) return

    ElMessageBox.confirm(`是否确认删除OA 请假申请编号为"${idsToDelete}"的数据项？`)
      .then(() => delLeave(idsToDelete))
      .then(() => {
        ElMessage.success("删除成功")
        getList()
      })
      .catch(() => {})
  }

  /** 导出操作 */
  const handleExport = () => {
    if (proxy?.download) {
      proxy.download('system/leave/export', {
        ...queryParams
      }, `leave_${new Date().getTime()}.xlsx`)
    } else {
      console.warn('下载方法未定义')
    }
  }

  /** 重置表单 */
  const resetForm = () => {
    form.id = null
    form.type = null
    form.reason = null
    form.startTime = null
    form.endTime = null
    form.day = null
    form.additionalHandler = []
    disabled.value = false
    flowStatus.value = ""

    if (formRef.value) {
      formRef.value.resetFields()
    }
  }
</script>